package com.yyw.foodie.service;

import com.alibaba.fastjson.JSON;
import com.yyw.foodie.utils.PagedGridResult;
import com.yyw.foodie.vo.SearchItemsVo;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author yiyw
 * @ClassName IndexSearch.java
 * @Description TODO
 * @createTime 2021年07月17日 13:31:00
 */
@Service
public class IndexSearch {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 首页搜索框搜索
     *
     * @param keyWords 关键字
     * @param sort     排序规则
     * @param page     当前页
     * @param pageSize 显示记录数
     * @return
     */
    public PagedGridResult itemsPage(String keyWords, String sort, Integer page, Integer pageSize) {
        // es 中 page 是从 0 开始的
        page--;
        SearchRequest searchRequest = new SearchRequest("foodie");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.from(page).size(pageSize);
        if (Objects.equals("c", sort)) {
            // 销量排序
            sourceBuilder.sort("sellCounts", SortOrder.DESC);
        } else if (Objects.equals("p", sort)) {
            // 价格
            sourceBuilder.sort("price", SortOrder.ASC);
        } else {
            // 默认
            sourceBuilder.sort("updated_time", SortOrder.DESC);
        }

        if (StringUtils.isNotBlank(keyWords)) {
            sourceBuilder.query(QueryBuilders.matchQuery("itemName", keyWords));
            // 构建高亮体
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.preTags("<span class = 'high'>");
            highlightBuilder.postTags("</span>");
            // 构建高亮字段
            highlightBuilder.field("itemName");
            sourceBuilder.highlighter(highlightBuilder);
        }

        searchRequest.source(sourceBuilder);
        // 执行查询
        try {
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            //获取搜索的文档结果
            SearchHits hit = response.getHits();
            SearchHit[] hits = hit.getHits();
            List<SearchItemsVo> itemsVos = new ArrayList<>();

            for (SearchHit searchHit : hits) {
                //将文档中的每一个对象转换json串值
                String sourceAsString = searchHit.getSourceAsString();
                //将json串值转换成对应的实体对象
                SearchItemsVo items = JSON.parseObject(sourceAsString, SearchItemsVo.class);
                //获取对应的高亮域
                Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                //高亮字段
                HighlightField highlightAddress = highlightFields.get("itemName");
                if (highlightAddress != null) {
                    // 为title串值增加自定义的高亮标签
                    Text[] titleTexts = highlightAddress.fragments();
                    String itemName = "";
                    for (Text text : titleTexts) {
                        itemName += text;
                    }
                    //将追加了高亮标签的串值重新填充到对应的对象
                    items.setItemName(itemName);
                }
                itemsVos.add(items);
            }

//            PagedGridResult result = PagedGridResult.setterPagedGrid(itemsVos, page);
            PagedGridResult result = new PagedGridResult();
            result.setPage(page + 1);
            Integer value = (int)hit.getTotalHits().value;
            int total = (value % pageSize) > 0 ? (value / pageSize) + 1 : (value / pageSize);
            result.setTotal(total);
            result.setRecords(value);
            result.setRows(itemsVos);
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            PagedGridResult result = PagedGridResult.setterPagedGrid(new ArrayList<>(), page);
            return result;
        }
    }
}
